/*
 * Copyright 2008 Zoundry LLC, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package org.zoundry.gaedt.core.util;

import java.io.CharArrayReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.util.jar.JarFile;
import test.org.zoundry.gaedt.core.ZGaeCoreTestCase;

/**
 * Tests the closer util class.
 */
public class ZGaeCloserTest extends ZGaeCoreTestCase
{
    /**
     * Test that close(null) works (doesn't throw an NPE).
     */
    public void testNullClosings()
    {
        ZGaeCloser.close((InputStream) null);
        ZGaeCloser.close((JarFile) null);
        ZGaeCloser.close((OutputStream) null);
        ZGaeCloser.close((Reader) null);
        ZGaeCloser.close((Writer) null);
    }

    /**
     * Test closing an input stream.
     */
    public void testInputStream() throws Exception
    {
        InputStream stream = this.getClass().getResourceAsStream("testJarFile.jar");
        assertTrue(stream.available() > 0);
        stream.read();
        assertTrue(stream.available() > 0);
        ZGaeCloser.close(stream);
        try
        {
            stream.available();
            fail("Should have seen an IOException because the stream was closed.");
        }
        catch (IOException e)
        {
            // Note: depending on the classloader (junit vs. junit plug-in), the error
            // message may be different so for now it is enough that we got an io exception
        }
    }

    /**
     * Test closing a jar file.
     */
    public void testJarFile() throws Exception
    {
        File file = createTestJarFile();

        JarFile jFile = new JarFile(file);
        jFile.entries();
        ZGaeCloser.close(jFile);
        try
        {
            jFile.entries();
            fail("Expected an error due to the jar file being closed.");
        }
        catch (IllegalStateException ise)
        {
            assertEquals("zip file closed", ise.getMessage());
        }
    }

    /**
     * Test closing an output stream.
     */
    public void testOutputStream() throws Exception
    {
        File file = File.createTempFile("_zgae_idc", ".txt");
        file.deleteOnExit();

        OutputStream oStream = new FileOutputStream(file);
        oStream.write(111);
        ZGaeCloser.close(oStream);
        try
        {
            oStream.write(112);
            fail("Should have failed with a 'Write error' error.");
        }
        catch (IOException e)
        {
            assertEquals("Write error", e.getMessage());
        }
    }

    /**
     * Test closing a reader.
     */
    public void testReader() throws Exception
    {
        Reader reader = new CharArrayReader(new char[] { 'a', 'b', 'c', 'd' });
        reader.read();
        ZGaeCloser.close(reader);
        try
        {
            reader.read();
            fail("Should have seen an IOException because the stream was closed.");
        }
        catch (IOException e)
        {
            assertEquals("Stream closed", e.getMessage());
        }
    }

    /**
     * Test closing a writer.
     */
    public void testWriter() throws Exception
    {
        File file = File.createTempFile("_zgae_idc", ".txt");
        file.deleteOnExit();

        Writer writer = new FileWriter(file);
        writer.write(111);
        ZGaeCloser.close(writer);
        try
        {
            writer.write(112);
            fail("Should have failed with a 'Write error' error.");
        }
        catch (IOException e)
        {
            assertEquals("Stream closed", e.getMessage());
        }
    }

    /**
     * Makes a temp file used for testing.
     *
     * @throws IOException
     * @throws FileNotFoundException
     */
    protected File createTestJarFile() throws IOException, FileNotFoundException
    {
        File file = File.createTempFile("_zgae_tjf", ".jar");
        file.deleteOnExit();
        InputStream inputStream = null;
        OutputStream outputStream = null;

        try
        {
            inputStream = ZGaeCloserTest.class.getResourceAsStream("testJarFile.jar");
            outputStream = new FileOutputStream(file);
            ZGaeFileUtil.copy(inputStream, outputStream);
        }
        finally
        {
            if (inputStream != null)
                inputStream.close();
            if (outputStream != null)
                outputStream.close();
        }
        return file;
    }
}
